package com.qmrssreader.reader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.qmrssreader.reader.R;
import com.qmrssreader.dto.GroupItem;
import com.qmrssreader.dto.RssItem;
import com.qmrssreader.system.CommonConfig;
import com.qmrssreader.system.DBAdapter;
import com.qmrssreader.system.ReallySimpleReader;
import com.qmrssreader.system.NotifyService;

public class QMRssReaderActivity extends Activity implements Runnable {

	DBAdapter db;
	Cursor cursor;

	ExpandableListAdapter mAdapter;
	ExpandableListView lstV;
	Button btnAdd;
	Button btnGroupManage;

	private ProgressDialog progressDialog;
	Thread thread;
	private boolean resumeHasRun = false;

	Dialog dialog;

	private void InitInfo() {
		dialog = new Dialog(QMRssReaderActivity.this);
		dialog.setContentView(R.layout.infomation);
		/*
		 * dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,
		 * WindowManager.LayoutParams.MATCH_PARENT);
		 */
		dialog.setCancelable(false);
		dialog.setCanceledOnTouchOutside(false);
		dialog.getWindow().getAttributes().windowAnimations = R.style.Animations_SmileWindow;
		// dialog.getWindow().getAttributes().
		dialog.setTitle(CommonConfig.info_about_name);
		TextView info_title = (TextView) dialog.findViewById(R.id.info_title);
		ImageView info_img = (ImageView) dialog.findViewById(R.id.info_img);
		TextView info_desc = (TextView) dialog
				.findViewById(R.id.info_description);
		Button info_OK = (Button) dialog.findViewById(R.id.info_btnOk);

		info_title.setText(CommonConfig.info_title);
		info_desc.setText(CommonConfig.info_description);
		info_OK.setVisibility(CommonConfig.INVISIBLE);

	}

	private void ShowInfor_Start() {
		InitInfo();
		dialog.show();
		final Timer t = new Timer();
		t.schedule(new TimerTask() {
			public void run() {
				dialog.dismiss();
				t.cancel();
			}
		}, 6000);
	}

	private void ShowInfor() {
		InitInfo();
		Button info_OK = (Button) dialog.findViewById(R.id.info_btnOk);
		info_OK.setVisibility(CommonConfig.VISIBLE);
		dialog.show();
		info_OK.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dialog.dismiss();
			}
		});
	}

	// EditText txtLink;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		this.setContentView(R.layout.main);
		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
				.permitAll().build();
		StrictMode.setThreadPolicy(policy);
		btnAdd = (Button) findViewById(R.id.btnAdd);
		btnGroupManage = (Button) findViewById(R.id.btnManageGroup);
		lstV = (ExpandableListView) findViewById(R.id.lstFeeds);

		startService(new Intent(QMRssReaderActivity.this, NotifyService.class));

		progressDialog = new ProgressDialog(this);
		progressDialog.setMessage(CommonConfig.DIALOG_PROGRESS);
		progressDialog.setCancelable(false);
		progressDialog.show();
		// System.out.println("Khoi dong lai chuong trinh");
		thread = new Thread(this);
		thread.start();
		ShowInfor_Start();
	}

	public static ArrayList<ArrayList<RssItem>> children;
	// ArrayList<String> groups;
	public static ArrayList<GroupItem> group;
	ReallySimpleReader rssR;
	ArrayList<RssItem> newItems = new ArrayList<RssItem>();

	private void InitData() {
		// Read
		try {
			FileInputStream fis = openFileInput("config.ini");
			BufferedReader br = new BufferedReader(new InputStreamReader(fis));
			String ss = null;
			if ((ss = br.readLine()) == null)
				ss = "1";
			CommonConfig.min_of_check = Integer.valueOf(ss);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			CommonConfig.min_of_check = 1;
		}
		// groups = new ArrayList<String>();
		group = new ArrayList<GroupItem>();
		children = new ArrayList<ArrayList<RssItem>>();

		cursor = db.getAllRss1();
		while (cursor.moveToNext()) {
			String name = cursor.getString(cursor
					.getColumnIndex(DBAdapter.KEY_NAME));
			String uri = cursor.getString(cursor
					.getColumnIndex(DBAdapter.KEY_LINK));
			if (name.startsWith("QM")) {
				// readMergedFeed(name, uri);
			} else {
				// readFromStorage(name, uri);

				ReallySimpleReader rssR = new ReallySimpleReader(uri);
				newItems = rssR.getRSSItems1();
				if (newItems == null) {
					Toast.makeText(QMRssReaderActivity.this,
							CommonConfig.CONNECT_URL_FAILED, Toast.LENGTH_LONG);
					readFromStorage(name, uri);
				} else {
					// ArrayList<String> arrString = new ArrayList<String>();
					// for (int i = 0; i < newItems.size(); i++) {
					// arrString.add(newItems.get(i).getTitle());
					// }
					// groups.add(name + "\n->Date: " + rssR.getPubDate());
					group.add(new GroupItem(name, uri, rssR.getPubDate()));

					// children.add(arrString);
					children.add(newItems);
					saveToStorage(name, uri);
				}
			}
		}

		cursor = db.getAllRss2();
		while (cursor.moveToNext()) {
			String name = cursor.getString(cursor
					.getColumnIndex(DBAdapter.KEY_NAME));
			String uri = cursor.getString(cursor
					.getColumnIndex(DBAdapter.KEY_LINK));
			readMergedFeed(name, uri);
		}
	}

	private void DisplayList() {
		StringBuilder sb = new StringBuilder();
		for (String s : fileList()) {
			sb.append(s + "\n");
		}

		// Set up our adapter
		mAdapter = new MyExpandableListAdapter(this);
		// lstV
		lstV.setAdapter(mAdapter);
		registerForContextMenu(lstV);

		OnClickListener lstnAdd = new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				showDialog(CommonConfig.DIALOG_NEW_RSS);
			}
		};
		btnAdd.setOnClickListener(lstnAdd);

		btnGroupManage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (resumeHasRun == false)
					resumeHasRun = true;
				Intent in = new Intent(QMRssReaderActivity.this, ManageActivity.class);
				startActivity(in);
			}
		});

		OnLongClickListener longLstn = new OnLongClickListener() {

			@Override
			public boolean onLongClick(View v) {
				// TODO Auto-generated method stub
				ShowInfor();
				return false;
			}
		};
		btnGroupManage.setOnLongClickListener(longLstn);
	}

	public void readMergedFeed(String name, String uri) {
		ArrayList<RssItem> vectParse = new ArrayList<RssItem>();
		String[] links = uri.split(CommonConfig.SPLIT_CHARACTER);
		Date pub = new Date(0);
		for (String link : links) {
			try {
				FileInputStream istream = openFileInput(link);
				DocumentBuilder builder = DocumentBuilderFactory.newInstance()
						.newDocumentBuilder();

				Document doc = builder.parse(istream);
				doc.getDocumentElement().normalize();
				NodeList nList = doc
						.getElementsByTagName(CommonConfig.XML_ELEMENT_ITEM);
				Date date = new Date(doc
						.getElementsByTagName(CommonConfig.XML_ELEMENT_PUBDATE)
						.item(0).getTextContent());
				if (date.after(pub))
					pub = date;
				// System.out.println();

				for (int temp = 0; temp < nList.getLength(); temp++) {

					Node nNode = nList.item(temp);
					if (nNode.getNodeType() == Node.ELEMENT_NODE) {
						// .out.println("" + temp);
						RssItem objBean;
						Element eElement = (Element) nNode;

						objBean = new RssItem();
						vectParse.add(objBean);

						Element _titleE = (Element) eElement
								.getElementsByTagName(
										CommonConfig.XML_ELEMENT_TITLE).item(0);
						Element _descriptionE = (Element) eElement
								.getElementsByTagName(
										CommonConfig.XML_ELEMENT_DESCRIPTION)
								.item(0);
						Element _pubDateE = (Element) eElement
								.getElementsByTagName(
										CommonConfig.XML_ELEMENT_PUBDATE).item(
										0);
						Element _linkE = (Element) eElement
								.getElementsByTagName(
										CommonConfig.XML_ELEMENT_LINK).item(0);

						objBean.setTitle(_titleE.getFirstChild().getNodeValue());
						/*
						 * String noHTMLString = _descriptionE.getFirstChild()
						 * .getNodeValue(); noHTMLString =
						 * noHTMLString.replaceAll("\\<.*?\\>", "");
						 * objBean.setDescription(noHTMLString);
						 */
						objBean.setDescription(_descriptionE.getTextContent());
						objBean.setLink(_linkE.getFirstChild().getNodeValue());
						Date _pubDate = new Date(_pubDateE.getFirstChild()
								.getNodeValue());
						objBean.setPubDate(_pubDate);
					}

				}
				istream.close();
			} catch (Exception e) {
				e.printStackTrace();

			}
		}
		newItems = vectParse;
		Collections.sort(newItems);
		children.add(newItems);
		// groups.add(name);
		group.add(new GroupItem(name, uri, pub));
	}

	private void readFromStorage(String name, String uri) {
		// System.out.println("aaaaaaaaaaaaaaaaaaaaaaa read from storage");
		ArrayList<RssItem> vectParse = new ArrayList<RssItem>();
		Date pub = new Date(0);
		try {
			FileInputStream istream = openFileInput(name);
			DocumentBuilder builder = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder();

			Document doc = builder.parse(istream);
			doc.getDocumentElement().normalize();
			NodeList nList = doc
					.getElementsByTagName(CommonConfig.XML_ELEMENT_ITEM);
			Date date = new Date(doc
					.getElementsByTagName(CommonConfig.XML_ELEMENT_PUBDATE)
					.item(0).getTextContent());
			if (date.after(pub))
				pub = date;
			// System.out.println();

			for (int temp = 0; temp < nList.getLength(); temp++) {

				Node nNode = nList.item(temp);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {
					// .out.println("" + temp);
					RssItem objBean;
					Element eElement = (Element) nNode;

					objBean = new RssItem();
					vectParse.add(objBean);

					Element _titleE = (Element) eElement.getElementsByTagName(
							CommonConfig.XML_ELEMENT_TITLE).item(0);
					Element _descriptionE = (Element) eElement
							.getElementsByTagName(
									CommonConfig.XML_ELEMENT_DESCRIPTION).item(
									0);
					Element _pubDateE = (Element) eElement
							.getElementsByTagName(
									CommonConfig.XML_ELEMENT_PUBDATE).item(0);
					Element _linkE = (Element) eElement.getElementsByTagName(
							CommonConfig.XML_ELEMENT_LINK).item(0);

					objBean.setTitle(_titleE.getFirstChild().getNodeValue());
					/*
					 * String noHTMLString = _descriptionE.getFirstChild()
					 * .getNodeValue(); noHTMLString =
					 * noHTMLString.replaceAll("\\<.*?\\>", "");
					 * objBean.setDescription(noHTMLString);
					 */
					objBean.setDescription(_descriptionE.getTextContent());
					objBean.setLink(_linkE.getFirstChild().getNodeValue());
					Date _pubDate = new Date(_pubDateE.getFirstChild()
							.getNodeValue());
					objBean.setPubDate(_pubDate);
				}
			}
			newItems = vectParse;
			// ArrayList<String> arrString = new ArrayList<String>();
			// for (int i = 0; i < newItems.size(); i++) {
			// arrString.add(newItems.get(i).getTitle());
			// }
			// groups.add(name + "--Public date: " + date + "--");
			group.add(new GroupItem(name, uri, pub));
			// children.add(arrString);
			children.add(newItems);

			istream.close();
		} catch (Exception e) {
			e.printStackTrace();

		}
	}

	private void saveToStorage(String name, String uri) {
		// System.out.println("aaaaaaaaaaaaaaaaaaaaaaa save to storage");
		try {
			URL url = new URL(uri);
			URLConnection con = url.openConnection();

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					con.getInputStream()));
			String inputLine;
			StringBuilder sb = new StringBuilder();
			while ((inputLine = reader.readLine()) != null)
				sb.append(inputLine + "\n");

			FileOutputStream fos = openFileOutput(name, MODE_PRIVATE);
			fos.write(sb.toString().getBytes());
			fos.close();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			Toast.makeText(QMRssReaderActivity.this, e.getMessage(),
					Toast.LENGTH_LONG).show();
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case CommonConfig.DIALOG_NEW_RSS:
			LayoutInflater factory = LayoutInflater.from(this);
			final View textEntryView = factory.inflate(R.layout.dialog_new_rss,
					null);

			return new AlertDialog.Builder(QMRssReaderActivity.this)
					.setTitle(CommonConfig.DIALOG_NEW_RSS_TITILE)
					.setView(textEntryView)
					.setIcon(R.drawable.dialog_question)
					// dialog.getWindow().getAttributes().windowAnimations=R.style.Animations_SmileWindow;

					.setPositiveButton("Add",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									/* User clicked OK so do some stuff */
									progressDialog.show();
									EditText txtLink = (EditText) textEntryView
											.findViewById(R.id.txtNewRssLink);
									final String link = txtLink.getText()
											.toString();
									Thread thrd = new Thread(new Runnable() {

										@Override
										public void run() {
											// TODO Auto-generated method stub
											Looper.prepare();
											((MyExpandableListAdapter) mAdapter)
													.addFeed(link, db);
											handler.sendEmptyMessage(1);
											Looper.loop();
										}
									});
									thrd.start();
								}
							})
					.setNegativeButton("Cancel",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									/* User clicked cancel so do some stuff */
								}
							}).create();
		}
		return null;
	}

	public void timerDelayRemoveDialog(long time, final Dialog d) {
		new Handler().postDelayed(new Runnable() {
			public void run() {
				d.dismiss();
			}
		}, time);
	}

	static File openedFileName;

	public class ViewHolder1 {
		ImageView img;

		public ImageView getImg() {
			return img;
		}

		public void setImg(ImageView img) {
			this.img = img;
		}

		public TextView getTitle() {
			return title;
		}

		public void setTitle(TextView title) {
			this.title = title;
		}

		TextView title;

		public ViewHolder1() {

		}
	}

	public class MyExpandableListAdapter extends BaseExpandableListAdapter {

		LayoutInflater inflater;
		LayoutInflater inflater_1;

		public MyExpandableListAdapter(Context context) {
			inflater = LayoutInflater.from(context);
			inflater_1 = LayoutInflater.from(context);
		}

		public void deleteAll() {
			// groups.clear();
			group.clear();
			children.clear();
			notifyDataSetChanged();
		}

		public boolean addFeed(String uri, DBAdapter db) {
			if (db.existsURL(uri)) {
				Toast.makeText(QMRssReaderActivity.this,
						"This feed already exists!!!", Toast.LENGTH_LONG)
						.show();
				return false;
			}
			rssR = new ReallySimpleReader(uri);
			newItems = rssR.getRSSItems1();
			if (newItems == null) {
				Toast.makeText(QMRssReaderActivity.this,
						CommonConfig.CONNECT_URL_FAILED, Toast.LENGTH_LONG)
						.show();
				return false;
			}

			String name = rssR.getTitle().trim();
			// groups.add(name + " --Public date: " + rssR.getPubDate() + "--");
			int index = 0;
			int size = group.size();
			if (size > 0) {
				while (index < size
						&& !group.get(index).getName()
								.startsWith(CommonConfig.MERGE_GROUP_PREFIX)
						&& group.get(index).getName().compareToIgnoreCase(name) < 0)
					index++;

			}
			group.add(index, new GroupItem(name, uri, rssR.getPubDate()));
			children.add(index, newItems);
			// notifyDataSetChanged();
			saveToStorage(name, uri);
			db.createRss(name, uri);
			return true;
		}

		public Object getChild(int groupPosition, int childPosition) {
			// return children[groupPosition][childPosition];
			return children.get(groupPosition).get(childPosition).getTitle();
		}

		public long getChildId(int groupPosition, int childPosition) {
			return childPosition;
		}

		public int getChildrenCount(int groupPosition) {
			// return children[groupPosition].length;
			return children.get(groupPosition).size();
		}

		public TextView getGenericView() {
			// Layout parameters for the ExpandableListView
			AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT, 64);

			TextView textView = new TextView(QMRssReaderActivity.this);
			textView.setLayoutParams(lp);
			// Center the text vertically
			textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
			// Set the text starting position
			textView.setPadding(36, 0, 0, 0);
			return textView;
		}

		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			View v = null;
			TextView tt = null;

			v = inflater.inflate(R.layout.feed_row, null);
			tt = (TextView) v.findViewById(R.id.tv_title);
			// final String myText = this.getChild(groupPosition, childPosition)
			// .toString();
			final RssItem myRss = children.get(groupPosition)
					.get(childPosition);

			tt.setText(myRss.getTitle());

			ImageView icon = (ImageView) v.findViewById(R.id.imgRowContent);
			icon.setImageResource(R.drawable.ic_arr);

			v.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View arg0) {
					// TODO Auto-generated method stub
					Intent in = new Intent(QMRssReaderActivity.this,
							ArticleDetailActivity.class);
					in.putExtra(CommonConfig.EXTRA_FEED_TITLE, myRss.getTitle());
					in.putExtra(CommonConfig.EXTRA_FEED_LINK, myRss.getLink());
					in.putExtra(CommonConfig.EXTRA_FEED_DESCRIPTION,
							myRss.getDescription());
					in.putExtra(CommonConfig.EXTRA_FEED_PUBDATE, myRss
							.getPubDate().toString());
					startActivity(in);
				}
			});
			return v;
		}

		public Object getGroup(int groupPosition) {
			// return groups.get(groupPosition);
			return group.get(groupPosition);
		}

		public int getGroupCount() {
			// return groups.size();
			return group.size();
		}

		public long getGroupId(int groupPosition) {
			return groupPosition;
		}

		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {

			View v = null;
			TextView txtName = null;
			TextView txtPubDate = null;

			v = inflater_1.inflate(R.layout.group_row, null);
			txtName = (TextView) v.findViewById(R.id.tv_feed_name);
			txtPubDate = (TextView) v.findViewById(R.id.tv_feed_pubdate);

			final GroupItem myRss = group.get(groupPosition);

			txtName.setText(myRss.getName());
			txtPubDate.setText(CommonConfig.SHOW_PUBDATE_PREFIX
					+ myRss.getPubDate().toString());

			return v;
		}

		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return true;
		}

		public boolean hasStableIds() {
			return true;
		}

	}

	@Override
	public void run() {
		Looper.prepare();
		db = new DBAdapter(this);
		db.open();
		InitData();
		handler.sendEmptyMessage(0);
		Looper.loop();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		if (resumeHasRun == true) {
			((MyExpandableListAdapter) mAdapter).notifyDataSetChanged();
		}
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message message) {
			switch (message.what) {
			case 0:
				progressDialog.dismiss();
				// thread.stop();
				DisplayList();
				break;
			case 1:
				progressDialog.dismiss();
				((MyExpandableListAdapter) mAdapter).notifyDataSetChanged();
				break;
			case 2:
				((MyExpandableListAdapter) mAdapter).notifyDataSetChanged();
				break;
			default:
				break;
			}
		}

	};

}